package other.system.client.sap;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.api.annotations.RequestMethod;
import com.rkhd.platform.sdk.api.annotations.RestApi;
import com.rkhd.platform.sdk.api.annotations.RestMapping;
import com.rkhd.platform.sdk.api.annotations.RestQueryParam;
import com.rkhd.platform.sdk.creekflow.approvalevent.ApprovalEvent;
import com.rkhd.platform.sdk.creekflow.approvalevent.ApprovalEventRequest;
import com.rkhd.platform.sdk.creekflow.approvalevent.ApprovalEventResponse;
import com.rkhd.platform.sdk.exception.ApiEntityServiceException;
import com.rkhd.platform.sdk.exception.AsyncTaskException;
import com.rkhd.platform.sdk.exception.ScriptBusinessException;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.service.FutureTaskService;
import com.rkhd.platform.sdk.service.XoqlService;
import com.rkhd.platform.sdk.task.FutureTask;
import other.system.client.apitool.SAPClientUtils;
import other.system.client.util.HCDateUtils;
import other.system.client.util.ResultBody;
import other.system.client.util.TfReturnMsgTools;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description 推送认领数据到SAP
 * @Author 黎炎松
 * 2024-07-18 17:20
 */
@RestApi(baseUrl = "/xsy/sap")
public class PushClaimToSap implements ApprovalEvent, FutureTask {
    private static XoqlService xoqlService = XoqlService.instance();
    private static final Logger logger = LoggerFactory.getLogger();
    private static String LOGGER_MSG = "推送认领数据到SAP ==> ";

    /**
     * 执行审批完成任务
     * @param request
     * @return
     */
    @Override
    public ApprovalEventResponse execute(ApprovalEventRequest request) {
        logger.info(LOGGER_MSG + "审批完成触发开始");
        logger.info("ObjectApiKey:" + request.getEntityApiKey() + " , DataId:" + request.getDataId());

        // 执行异步任务
        try {
            // doPushClaimToSap(request.getDataId());
            String messageId = FutureTaskService.instance().addFutureTask(getClass(), String.valueOf(request.getDataId()));
            logger.info(LOGGER_MSG + "异步ID:" + messageId);
        } catch (AsyncTaskException e) {
            throw new RuntimeException(e);
        }

        ApprovalEventResponse response = new ApprovalEventResponse();
        response.setSuccess(true);
        response.setMsg("success");
        return response;
    }

    /**
     * 执行异步任务
     * @param s
     * @throws ScriptBusinessException
     */
    @Override
    public void execute(String s) throws ScriptBusinessException {
        logger.info(LOGGER_MSG + "******开始执行异步任务");
        doPushClaimToSap(Long.valueOf(s));
        logger.info(LOGGER_MSG + "******执行异步任务结束");
    }

    /**
     * 手动推送客户数据
     * @param claimId
     * @return
     */
    @RestMapping(value = "/pushClaimToSap", method = RequestMethod.POST)
    public String doOpt(@RestQueryParam(name = "id") Long claimId) throws ApiEntityServiceException {
        logger.info(LOGGER_MSG + "执行了按钮事件 = " + claimId);
        try {
            String messageId = FutureTaskService.instance().addFutureTask(getClass(), String.valueOf(claimId));
            logger.info(LOGGER_MSG + "异步ID:" + messageId);
        } catch (AsyncTaskException e) {
            throw new RuntimeException(e);
        }
        return TfReturnMsgTools.getSuccessResult("推送成功");
    }

    public static void main(String[] args) throws ApiEntityServiceException {
        new PushClaimToSap().doPushClaimToSap(3423401028344385L);
    }

    /**
     * 推送认领数据到SAP  (需要使用异步，否则会出现链接sap超过15秒导致超时的情况)
     * @param claimId
     * @return
     */
    public String doPushClaimToSap(Long claimId) {
        try {

            // 获取认领数据
            logger.info(LOGGER_MSG + "处理开始: " + claimId);
            String sql = "select id,bankStatement__c.name bankStatementName,bankStatement__c.serialNumber__c serialNumber,bankStatement__c.collectingUnit__c.name collectingUnitName,bankStatement__c.customerUnit__c.accountName customerUnitName," +
                    "bankStatement__c.customItem7__c customItem7,bankStatement__c.customItem4__c customItem4,bankStatement__c.actualAmount__c actualAmount," +
                    "bankStatement__c.YnAdvanceReceipts__c YnAdvanceReceipts,bankStatement__c.bankAccount__c bankAccount,bankStatement__c.amountRefunded__c amountRefunded " +
                    " from claim__c where id = " + claimId;
            List<JSONObject> invoiceList = xoqlService.query(sql, true).getRecords();
            if (invoiceList.size() <= 0) {
                logger.error(LOGGER_MSG + "查询认领数据异常");
                return TfReturnMsgTools.getFailResult("查询认领数据异常");
            }

            // 获取主表数据
            JSONObject claim = invoiceList.get(0);

            // 资金到账时间
            String paymentDateStr = "";
            Long paymentDate = claim.getLong("customItem4");
            if (paymentDate != null) {
                paymentDateStr = HCDateUtils.longToString(paymentDate, "yyyyMMdd");
            }

            // 收款（银行流水）编号 有退款需要增加退款标识
            String bankStatementName = claim.getString("bankStatementName");
            Double amountRefunded = claim.getDouble("amountRefunded");
            if (amountRefunded != null && amountRefunded > 0) {
                bankStatementName += "_TK";
            }

            // 获取开票明细
            sql = "select id,name,claimDetailsID__c,booking__c.name bookingName,receivableNumber__c.name  receivableNumber,receivablesDetail__c.name receivablesDetail," +
                    "orderNumber__c.po orderNumber,orderNumber__c.pmsProjectNo__c pmsProjectNo,amountClaimed__c " +
                    " from claimDetails__c where claim__c = " + claimId;
            List<JSONObject> claimDetailList = xoqlService.query(sql, true).getRecords();

            JSONArray sendData = new JSONArray();
            for (JSONObject claimDetail : claimDetailList) {
                JSONObject formData = new JSONObject();

                formData.put("NAME", bankStatementName); // 收款（银行流水）编号
                formData.put("SERIALNUMBER__C", claim.getString("serialNumber")); // 银行流水号
                formData.put("COLLECTINGUNIT__C", claim.getString("collectingUnitName")); // 收款单位（公司名称
                formData.put("CUSTOMERUNIT__C", claim.getString("customerUnitName")); // 客户单位(客户名称)
                formData.put("CUSTOMITEM7__C", claim.getString("customItem7")); // 客户编码
                formData.put("CUSTOMITEM4__C", paymentDateStr); // 资金到账时间
                formData.put("AMOUNTRECEIVED__C", claim.getString("actualAmount")); // 回款金额 （实际收款金额 = 收款金额 - 已退款金额）
                formData.put("YNADVANCERECEIPTS__C", getOptionStr(claim.getJSONArray("YnAdvanceReceipts"))); // 是否预收
                formData.put("BANKACCOUNT__C", claim.getString("bankAccount")); // 银行账户（收款账户）

                formData.put("NAME2", claimDetail.getString("name")); // 认领编号
                formData.put("CLAIMDETAILSID__C", claimDetail.getString("claimDetailsID__c")); // 认领明细ID
                formData.put("BOOKING__C", claimDetail.getString("bookingName")); // BOOKING
                formData.put("RECEIVABLENUMBER__C", claimDetail.getString("receivableNumber")); // 应收单号
                formData.put("RECEIVABLESDETAIL__C", claimDetail.getString("receivablesDetail")); // 应收明细单
                formData.put("PROJECTNUMBER__C", claimDetail.getString("pmsProjectNo")); // 项目号
                formData.put("ORDERNUMBER__C", claimDetail.getString("orderNumber")); // 合同号
                formData.put("AMOUNTCLAIMED__C", claimDetail.getString("amountClaimed__c")); // 认领金额

                sendData.add(formData);
            }

            // 拼接发送参数
            JSONObject reqBody = new JSONObject();
            reqBody.put("IT_HKXX", sendData);
            logger.info(LOGGER_MSG + "发送的数据: " + reqBody);

            // 推送到SAP
            ResultBody resultBody = SAPClientUtils.sendPost(reqBody, SAPClientUtils.PAYMENT_URL, "");
            logger.debug(LOGGER_MSG + "resultBody:" + resultBody);
            if (!Objects.equals(resultBody.getCode(), "200")) {
                logger.error(LOGGER_MSG + "推送异常: " + resultBody.getMessage());
                return TfReturnMsgTools.getFailResult("推送异常:" + resultBody.getMessage());
            }

            logger.info(LOGGER_MSG + "推送成功");
            return TfReturnMsgTools.getSuccessResult("推送成功");
        } catch (Exception e) {
            logger.error(LOGGER_MSG + "处理异常: " + e.getMessage());
            return TfReturnMsgTools.getFailResult("推送异常:" + e.getMessage());
        }
    }

    /**
     * 获取选项的字符串值
     * @param optionArr
     * @return
     */
    public String getOptionStr(JSONArray optionArr) {
        String optStr = "";
        if (optionArr != null && optionArr.size() > 0) {
            optStr = optionArr.stream().map(v -> v.toString()).collect(Collectors.joining(","));
        }
        return optStr;
    }


}
